package com.i2863.receipt.service.impl;

import com.i2863.receipt.dao.ActivityRepository;
import com.i2863.receipt.dao.WinnerRepository;
import com.i2863.receipt.entity.Activity;
import com.i2863.receipt.service.ActivityService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2018/6/8.
 */
@Service
public class ActivityServiceImpl implements ActivityService{

    @Resource
    private ActivityRepository activityRepository;

    @Resource
    private WinnerRepository winnerRepository;


    private final static Logger logger = LoggerFactory.getLogger(ActivityServiceImpl.class);

    @Override
    public Activity findOne(Integer id) {
        return activityRepository.findOne(id);
    }

    @Override
    public void add(Activity activity) {
        activityRepository.save(activity);
    }

    @Override
    public void del(List<Activity> list) {
        activityRepository.delete(list);
    }

    @Override
    public void update(Activity activity) {
        activityRepository.saveAndFlush(activity);
    }

    /**
     *查询站点下的所有活动并按活动期数来倒序排列
     * @param siteId
     * @return
     */
    @Override
    public List<Activity> findListBySiteId(final Integer siteId) {
        return activityRepository.findAll(new Specification<Activity>() {
            @Override
            public Predicate toPredicate(Root<Activity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                //拼接查询条件
                list.add(criteriaBuilder.equal(root.get("site").get("id").as(Integer.class),siteId));
                //拼接排序条件
                Predicate[] p = new Predicate[list.size()];
                criteriaQuery.where(criteriaBuilder.and(list.toArray(p)));
                criteriaQuery.orderBy(criteriaBuilder.desc(root.get("num")));
                return criteriaQuery.getRestriction();
            }
        });
    }

    @Override
    public List<Activity> findOneByNow(Integer siteId) {
        return activityRepository.findOneByNow(siteId);
    }

    @Override
    public Activity findOneById(Integer id) {
        return activityRepository.findOne(id);
    }

    @Override
    public Page<Activity> queryByPage(final Integer siteId, Integer pageSize,
                                      Integer pageNum, final String queryContent,
                                      final String startTime,final String endTime) {


        Pageable pageable = new PageRequest(pageNum-1,pageSize, Sort.Direction.DESC,"num");//jpa从0开始
        //规格定义
        Specification<Activity> specification = new Specification<Activity>() {
            /**
             * 构造断言
             * @param root 实体对象引用
             * @param query 规则查询对象
             * @param cb 规则构建对象
             * @return 断言
             */
            @Override
            public Predicate toPredicate(Root<Activity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>(); //所有的断言
                if(StringUtils.isNotBlank(queryContent)){ //添加断言
                    Predicate likeName = cb.like(root.get("name").as(String.class),"%"+queryContent+"%");
                    predicates.add(likeName);
                }
                if(StringUtils.isNotBlank(startTime)){
                    Predicate start = cb.greaterThanOrEqualTo(root.get("startTime").as(String.class),startTime);
                    predicates.add(start);
                }
                if(StringUtils.isNotBlank(endTime)){
                    Predicate end = cb.lessThanOrEqualTo(root.get("endTime").as(String.class),endTime);
                    predicates.add(end);
                }
                predicates.add(cb.equal(root.get("site").get("id").as(Integer.class),siteId));
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return activityRepository.findAll(specification,pageable);
    }

    @Override
    public Integer countBySiteId(Integer siteId) {
        return activityRepository.countBySiteId(siteId);
    }

    @Override
    public List<Activity> findListByIds(List<Integer> ids) {
        return activityRepository.findAll(ids);
    }

    @Transactional
    @Override
    public void reset(Integer activityId) {
        winnerRepository.deleteByActivityId(activityId);
        activityRepository.updateActivityStatus(Activity.NOTSTARTED,activityId);
    }

    @Transactional
    @Override
    public void resetInside(Integer activityId) {
        winnerRepository.resetInside(activityId);
        activityRepository.updateActivityStatus(Activity.STARTED,activityId);

    }

    @Transactional
    @Override
    public void resetLottery(Integer activityId) {
        winnerRepository.resetLottery(activityId);
        activityRepository.updateActivityStatus(Activity.SECOND_ROUND,activityId);
    }

    @Override
    public Integer getMaxActivityNum(Integer siteId) {
        return activityRepository.getMaxActivityNum(siteId);
    }

    @Transactional
    @Override
    public void finishActivity(Integer activityId) {
        activityRepository.finishActivity(activityId);
    }


}
